home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PD Collection CD 1
/
PD Collection CD 1.iso
/
textual
/
pdimpres
/
!PD-Impres
/
c
/
pd-dff
next >
Wrap
Text File
|
1990-08-25
|
14KB
|
356 lines
/* -> c.pd-dff */
/*
* Program to convert PipeDream files into text files suitable for Impression, while still retaining style and formatting
* information where possible.
* ie This program converts PipeDream files into DDF format
*
* © Stuart Hickinbottom 27mar90
*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <signal.h>
/* Macro definitions */
#define Special_character '%' /* The special character that indicates a command */
#define Max_highlight_size 12 /* The maximum length of a PipeDream highlight code, I think this is column definition */
#define BOOL int /* Define a 'type' BOOL */
#define TRUE 1 /* Define the value of TRUE */
#define FALSE 0 /* Define the value of FALSE */
#define Buffer_increase 256 /* Define the amount by which the buffer is incremented. Should be >= max DDF line length */
#define My_name "pd-dff"
#define Brief_help "convert PipeDream files into DDF files"
#define Version_number "1.01"
#define Version_date "Mar 27 1990"
#define My_credits "© Stuart Hickinbottom 1990"
/* Global variables */
static char in_file_name[255]; /* Filespec of PipeDream file to convert */
static char *in_file = in_file_name; /* Define a pointer to this name */
static char out_file_name[255]; /* Filespec of DDF format output file */
static char *out_file = out_file_name; /* Define a pointer to this name */
static char *pd_text = NULL; /* Pointer to loaded PipeDream text in memory */
static char *ddf_text = NULL; /* Pointer to DDF format converted text */
static int ddf_size; /* The size of the DDF text buffer. Increases */
static int offset_ddf = 0; /* The offset into the DDF text buffer */
static int offset_pd = 0; /* The offset into the PD text buffer */
static BOOL verbose = FALSE; /* Flag to indicate verbose operation */
/*
* This table defines the translation from PipeDream highlight codes to Impression DDF commands. For each highlight code
* there is the PipeDream command name and then the Impression style name. There is then a flag which this code uses to
* remember whether the style is currently on or off. This table may be freely expanded.
*/
static char *highlight_trans[][] =
{
{"H1", "Underline", "Off"}, /* Style: Underline */
{"H2", "Bold", "Off"}, /* Style: Bold */
{"H3", "Main Heading", "Off"}, /* Style: Extended sequence */
{"H4", "Italic", "Off"}, /* Style: Italic */
{"H5", "Subscript", "Off"}, /* Style: Subscript */
{"H6", "Superscript", "Off"}, /* Style: Superscript */
{"H7", "Typewriter", "Off"}, /* Style: Alternative font */
{"H8", "Sub-heading", "Off"}, /* Style: User defined */
{"JL", "Fully Justify", "Off"}, /* Style: Justified */
{"JR", "Fully Justify", "Off"}, /* Style: Justified */
{"C", "Centre", "Off"}, /* Justify: Centre */
{"**", "", "" } /* Terminating value */
};
static char *highlight_ignore[] = /* Define highlight codes which cause the 'interpreter' to skip the line */
{
"OP", /* Ignore page description lines */
"**", /* Terminating value */
};
/* Table of special highlights which are converted directly into text, for example the percentage symbol */
static char *highlight_text[][] =
{
{"PC", "%" }, /* Convert PC into the percentage symbol */
{"**", "" } /* Terminating value */
};
/* Any highlight code which is not in any of the above tables is simply skipped over - no action is taken */
int main(int argc, char *argv[])
{
void convert_pd_file(int), write_ddf_file(void), clean_up(void), give_help(void), describe_function(void), handle_escape(int);
int read_pd_file(void), pd_file_size, arg_num, strcpy(char *, char *), last_flag;
char *arg;
signal(SIGINT, handle_escape);
last_flag = 0;
for (arg_num = 1; arg_num < argc; ++arg_num)
{
arg = argv[arg_num];
if (arg[0] == '-')
{
last_flag = arg_num;
if (arg[1] == 'd' || arg[1] == 'D')
describe_function();
else
if (arg[1] == 'h' || arg[1] == 'H') give_help();
else
if (arg[1] == 'v' || arg[1] == 'V') verbose = TRUE;
else
{
fprintf(stderr, "%s: unknown flag '%s', try '-help'\n", My_name, arg);
exit(EXIT_SUCCESS);
}
}
}
if ((argc - last_flag) < 3)
{
fprintf(stderr, "%s: (Fatal) bad args - use '-help' if in need of help\n", My_name);
exit(EXIT_FAILURE);
}
strcpy(in_file_name, argv[last_flag+1]);
strcpy(out_file_name, argv[last_flag+2]);
pd_file_size = read_pd_file();
convert_pd_file(pd_file_size);
write_ddf_file();
clean_up();
if (verbose) fprintf(stderr, "%s: conversion complete\n", My_name);
}
/* Give help on syntax */
void give_help(void)
{
fprintf(stderr, "\n%s vsn %s [%s] - %s\n\n", My_name, Version_number, Version_date, Brief_help);
fprintf(stderr, "%s [options] infile outfile\n\n",My_name);
fprintf(stderr, "Options:-\n");
fprintf(stderr, "-describe describe what the program does\n");
fprintf(stderr, "-help give help on syntax\n");
fprintf(stderr, "-verbose give information on progress\n\n");
fprintf(stderr, "Example:-\n %s pipe_file ddf_file\n\n%s\n", My_name, My_credits);
exit(EXIT_SUCCESS);
}
/* Describe the programs method of operation */
void describe_function(void)
{
int highlight_number = 0;
int strcmp(char *, char *);
fprintf(stderr, "\n\
%s translates a PipeDream document into a DDF (document description\n\
format) file which is suitable for inclusion in packages such as Computer\n\
Concepts' Impression. Highlight codes are converted into the corresponding DDF\n\
style names (eg. hightlight 1 is 'Bold'), and incompatable highlights are\n\
ignored (eg. the definition of a heading or footer is skipped over). Styles are\n\
always turned off at the end of lines (as is the case in PipeDream).\n\
Note: because of the way in which PipeDream formats text, paragraphs will\n\
have to be editied to remove the carriage-returns at the end of each line.\n\
There is no way that this could be performed automatically, reliably.\n\
Currently, the following highlight conversions are performed:\n\n", My_name);
while (strcmp(highlight_trans[highlight_number][0], "**") != 0)
{
fprintf(stderr, "%6s ... %s\n", highlight_trans[highlight_number][0], highlight_trans[highlight_number][1]);
highlight_number++;
}
fprintf(stderr, "\n");
exit(EXIT_SUCCESS);
}
/* Read in the PipeDream file, allocating enough space to hold the entire file in one go */
int read_pd_file(void)
{
FILE *pd_file_handle;
int pd_file_size;
char *malloc(long);
void clean_up(void);
if (verbose) fprintf(stderr, "%s: opening file '%s'", My_name, in_file);
if ((pd_file_handle = fopen(in_file, "r")) == NULL)
{
if (verbose) fprintf(stderr, "\n");
fprintf(stderr, "%s: (Fatal) file '%s' could not be opened (not found?)\n", My_name, in_file);
exit(EXIT_FAILURE);
}
fseek(pd_file_handle, 0,2);
pd_file_size = (int)ftell(pd_file_handle);
fseek(pd_file_handle, 0,0);
if (verbose) fprintf(stderr, ", file size is %d bytes\n", pd_file_size);
if ((pd_text = malloc(pd_file_size)) == NULL)
{
fprintf(stderr, "%s: (Fatal) insufficient memory to load '%s'\n", My_name, in_file);
if (verbose) fprintf(stderr, "%s: closing file '%s'\n", My_name, in_file);
fclose(pd_file_handle);
clean_up();
exit(EXIT_FAILURE);
}
if (verbose) fprintf(stderr, "%s: reading text from file '%s'\n", My_name, in_file);
fread(pd_text, 1, pd_file_size, pd_file_handle);
if (verbose) fprintf(stderr, "%s: closing file '%s'\n", My_name, in_file);
fclose(pd_file_handle);
return(pd_file_size);
}
/* Write out the DDF format version of the text to a file */
void write_ddf_file(void)
{
FILE *ddf_file_handle;
void clean_up(void);
int chars_written;
if (verbose) fprintf(stderr, "%s: opening file '%s'\n", My_name, out_file);
if ((ddf_file_handle = fopen(out_file, "w")) == NULL)
{
fprintf(stderr, "%s: (Fatal) file '%s' could not be opened (disc full?)\n", My_name, out_file);
clean_up();
exit(EXIT_FAILURE);
}
if (verbose) fprintf(stderr, "%s: writing to file '%s'\n", My_name, out_file);
chars_written = fwrite(ddf_text, 1, offset_ddf, ddf_file_handle);
if (chars_written != offset_ddf)
{
fprintf(stderr, "%s: (Fatal) write error, %d bytes written (disc full/corrupted?)\n", My_name, chars_written);
clean_up();
exit(EXIT_FAILURE);
}
if (verbose) fprintf(stderr, "%s: closing file '%s'\n", My_name, out_file);
fclose(ddf_file_handle);
}
/* Clean up at the end of the conversion, or if an error has occured - ie free memory etc. */
void clean_up(void)
{
free(pd_text);
free(ddf_text);
}
/* Convert the PipeDream file into a DDF format file - this is the biggie!! */
void convert_pd_file(int pd_file_size)
{
void handle_embedded(void), all_highlights_off(void), ensure_highlights_off(void), increase_buffer(char *), clean_up(void);
char *malloc(int);
if (verbose) fprintf(stderr, "%s: converting text\n", My_name);
ddf_size = 0;
increase_buffer(NULL);
ddf_text = malloc(Buffer_increase);
if (ddf_text == NULL)
{
fprintf(stderr, "%s: (Fatal) unable to allocate store for DDF text\n", My_name);
clean_up();
exit(EXIT_FAILURE);
}
all_highlights_off();
while (offset_pd < pd_file_size)
{
while (pd_text[offset_pd] == Special_character) handle_embedded(); /* Handle highlight */
if ((pd_text[offset_pd] == '\x0a') || (pd_text[offset_pd] == '\x0d')) ensure_highlights_off();
if (offset_pd < pd_file_size) ddf_text[offset_ddf++] = pd_text[offset_pd];
offset_pd++;
if ((ddf_size - offset_ddf) < Buffer_increase) /* If the DDF text buffer needs to be increased... */
{
increase_buffer(ddf_text);
}
}
}
/* Handle an embedded command, converting it into DDF */
void handle_embedded(void)
{
char character, *highlight, *malloc(int);
int highlight_size, highlight_number, strcmp(char *, char *);
void toggle_highlight_on(int), insert_ddf(int);
highlight = malloc(Max_highlight_size);
highlight_size = 0;
while ((character = pd_text[++offset_pd]) != Special_character) highlight[highlight_size++] = character; /* Read command */
offset_pd++;
highlight[highlight_size] = NULL;
highlight_number = 0;
while ((strcmp(highlight_ignore[highlight_number], "**") != 0) && strcmp(highlight_ignore[highlight_number], highlight) != 0)
highlight_number++; /* Check if this command is to be ignored */
if (strcmp(highlight_ignore[highlight_number], "**") != 0) /* If this command should be ignored then... */
while ((pd_text[offset_pd] != '\x0a') && (pd_text[offset_pd++] != '\x0d')); /* Skip the rest of this line */
else
{
highlight_number = 0;
while ((strcmp(highlight_trans[highlight_number][0], "**") != 0) && strcmp(highlight_trans[highlight_number][0], highlight) != 0)
highlight_number++; /* Check if this command is to be translated to a DDF command */
if (strcmp(highlight_trans[highlight_number][0], "**") != 0) /* If this command should be translated then... */
{
toggle_highlight_on(highlight_number);
insert_ddf(highlight_number);
}
else
{
highlight_number = 0;
while ((strcmp(highlight_text[highlight_number][0], "**") != 0) && strcmp(highlight_text[highlight_number][0], highlight) != 0)
highlight_number++; /* Check if this command is to be translated to a text alternative */
if (strcmp(highlight_text[highlight_number][0], "**") != 0) /* If this command should be translated then... */
offset_ddf += sprintf(ddf_text+offset_ddf, "%s", highlight_text[highlight_number][1]); /* Copy in the translated string */
}
}
free(highlight);
}
/* Increase the buffer for the DDF text by the amount defined by Buffer_increase */
void increase_buffer(char *ddf_text)
{
void clean_up(void);
ddf_text = realloc(ddf_text, Buffer_increase);
if (ddf_text == NULL)
{
fprintf(stderr, "%s: (Fatal) unable to allocate store to DDF text buffer\n", My_name);
clean_up();
exit(EXIT_FAILURE);
}
ddf_size += Buffer_increase;
}
/* Toggle my flag which indicates whether a highlight is currently turn on. Used to turn all off at end of a line */
void toggle_highlight_on(int highlight_number)
{
if (highlight_trans[highlight_number][2] == "Off")
highlight_trans[highlight_number][2] = "On";
else
highlight_trans[highlight_number][2] = "Off";
}
/* This inserts the DDF equivalent of the highlight code, using the 'on flag' to decide whether to turn it on or off */
void insert_ddf(int highlight_number)
{
offset_ddf += sprintf(ddf_text+offset_ddf, "{\"%s\" %s}", highlight_trans[highlight_number][1], highlight_trans[highlight_number][2]);
}
/* Reset all the highlights to be initially off */
void all_highlights_off(void)
{
int highlight_number, strcmp(char *, char *);
highlight_number = 0;
while (strcmp(highlight_trans[highlight_number][0], "**") != 0)
highlight_trans[highlight_number++][2] = "Off";
}
/* Ensure that all highlights are off at the end of a line, by issuing 'off' DDF commands to turn highlights off */
void ensure_highlights_off(void)
{
int highlight_number, strcmp(char*, char*);
void toggle_highlight_on(int), insert_ddf(int);
highlight_number = 0;
while (strcmp(highlight_trans[highlight_number][0], "**") != 0)
{
if (highlight_trans[highlight_number][2] == "On")
{
toggle_highlight_on(highlight_number);
insert_ddf(highlight_number);
}
highlight_number++;
}
}
/* Called when escape signal received */
void handle_escape(int signo)
{
void clean_up(void);
fprintf(stderr, "%s: interrupt received from user - conversion aborted\n", My_name);
signal(signo, handle_escape);
clean_up();
exit(EXIT_FAILURE);
}